﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ecopsy.DataTier;
using AgencyEntityLib.Context;
using Ecopsy.Tools;
using SqlLibrary;
using Ecopsy.DataTier.SqlLibrary;
using System.Reflection;


namespace AgencyEntityLib.BaseEntity
{
    /// <summary>
    /// Описание контракта
    /// </summary>
    public class Contract : BusinessRulesEntity, ISqlSignature 
    {


        public class ContractStatusHistory : EntityList
        {
            public override void Add(object obj)
            {
                base.Add(obj);
            }
        }

        private string _Number = string.Empty;

        public override string ID
        {
            get
            {
                return base.ID;
            }
            set
            {
                base.ID = value;
                foreach (ContractSurfaceItem i in ContractSurfaceItemList)
                {
                    i.ContractID = value;
                }
            }
        }
        
        /// <summary>
        /// Номер контракта
        /// </summary>
        public string Number 
        { get { return _Number; } 
            set {

                bool bOk = this.BusinesRulesEngine.OwnerChanging ("Number",value );
                if (bOk)                
                    _Number = value; } 
        }

        private DateTime  _SignDate = DateTime .Now ;
        
        /// <summary>
        /// Дата  (для рекламы,и бронирования - дата создания) 
        /// Для контракта дата создания (плана платежей)
        /// </summary>
        public DateTime SignDate { get { return _SignDate; } set { _SignDate = value; } }

        /// <summary>
        /// Дата начала контракта = дате начала по первой поверхности - если поверхностей нет - первый день текущего месяца
        /// </summary>
        public DateTime StartDate
        {
            get
            {
                return ContractSurfaceItemList.GetMinStartDate();
                
            }
        }

        /// <summary>
        /// Дата начала контракта = дате окончания по второй поверхности - если поверхностей нет - последний день текущего месяца
        /// </summary>
        public DateTime EndDate
        {
            get
            {
                return ContractSurfaceItemList.GetMaxEndDate() ;
            }         
        }
               
               
        private Client _Client;
        /// <summary>
        /// Клиент
        /// </summary>
        public Client Client { get { return _Client; } 
            set 
            {
                bool bOk = this.BusinesRulesEngine.OwnerChanging("Client", value);
                if (bOk)            
                    _Client = value;

                this.BusinesRulesEngine.OwnerAfterChange("Client");
            } 
        }
        
        /// <summary>
        /// Тип контракта - контракт/бронь/реклама 
        /// Если - у контракта нет заказчика - это самореклама или соц. реклама
        /// Если нет графика платежей - это бронь 
        /// Есть -график - подписанный контракт. 
        /// </summary>                
        public  ContractStatus ContractStatus 
        {
            get 
            {   
                    return _ContractStatus;
 
            }
            set 
            {
                ///События в бизнесс правила - если ок - меняем статус
                bool bOk = this.BusinesRulesEngine.OwnerChanging("ContractStatus", value);
                if (bOk)
                {
                    if(null!=_ContractStatus)
                        StatusHistory.Add(_ContractStatus);

                    _ContractStatus = value;                    
                    BusinesRulesEngine.OwnerAfterChange(Contract_BusinesRulesEngine.CalculateContractSurfaceItemList); 
                    // Пишем историю 
                    
                }

            }
        }

        private ContractStatus _ContractStatus =null;



        private ContractStatusHistory _StatusHistory = new ContractStatusHistory();
        public ContractStatusHistory StatusHistory
        {
            get { return _StatusHistory; }
        }
        
        private ContractSurfaceItemList _ContractSurfaceItemList = new ContractSurfaceItemList();
        /// <summary>
        /// Список сторон принадлежащих контракту. Коллекция ContractSurfaceItem
        /// </summary>
        public ContractSurfaceItemList ContractSurfaceItemList
        {
            get 
            {  
                return _ContractSurfaceItemList; 
            }

            set { _ContractSurfaceItemList = value; }
            
        }

        
        

        [EntityNonSerialized]
        protected override string TagName
        {
            get
            {
                return "Contract";
            }
        }

        [EntityNonSerialized]
        protected override string ReportTypeExt
        {
            get
            {
                return "ContractExt";
            }
        }

        #region ISqlSignature Members

        public string SaveProcedure
        {
            get { return "ContractSave"; }
        }

        public string DeleteProcedure
        {
            get { throw new NotImplementedException(); }
        }

        public string LoadProcedure
        {
            get { return "ContractLoad"; }
        }

        #endregion


        #region Методы
        private static DateTime GetMinMax(ContractSurfaceItem[] L, System.Web.UI.WebControls.SortDirection SortDirection, string SortField)
        {
            ListWhere w = new ListWhere();
            w.SortCondition.fnOrderBy = SortFunctions.fOrderBy;
            w.SortCondition.SortField = SortField;
            w.SortCondition.SortDirection = SortDirection;
            Array.Sort(L, w.SortCondition);
            return (SortField == "dtStart" ? L[0].DtStart : L[0].DtFinish);

        }

        /// <summary>
        /// Вернуть текстом - статус контракта
        /// </summary>
        /// <param name="_Contract"></param>
        /// <returns></returns>   
        public  string GetTxtContractStatus()
        {

            wsDictionary ws = (wsDictionary)AgencyLib_GlobalConstants.CurrentAgency.WS_FactoryList[WS_FactoryList.wsKey_Dictionary]; ;
            List<DictionaryItem> l = ws.GetDictionary(AgencyLib_GlobalConstants.Dictionary_ContractType);
            foreach (DictionaryItem i in l)
            {
                if (i.ID == ContractStatus.ID)
                    return i.Value.ToString();
            }
            return string.Empty;
        }



        /// <summary>
        /// Сумма платежей по плану платежей
        /// </summary>
        /// <param name="_Contract"></param>
        /// <returns></returns>
        public double GetPlanPaymentsSumma()
        {
            if (!(ContractStatus is ContractStatus_Contract))
                return 0;

            return (ContractStatus as ContractStatus_Contract).PaymentsPlan.Summa;
        }
        /// <summary>
        /// Сумма платежей 
        /// </summary>
        /// <param name="_Contract"></param>
        /// <returns></returns>
        public  double GetPaymentsSumma()
        {
            if (!(ContractStatus is ContractStatus_Contract))
                return 0;

            ContractStatus_Contract St = (ContractStatus_Contract)ContractStatus;

            if (null == St.Payments)
                return 0;

            return St.Payments.Summa;
        }

        /// <summary>
        /// Разница между планом платежей и платежами
        /// </summary>
        /// <param name="_Contract"></param>
        /// <returns></returns>
        public  double GetRests()
        {
            return GetPlanPaymentsSumma() - GetPaymentsSumma();
        }

        /// <summary>
        /// Текущя задолженость 
        /// сумма по плану до ближайшего платежного дня вычесть 
        /// сумма платежей до текщего дня    
        /// </summary>
        /// <returns></returns>
        public  double GetCurrentRests()
        {
            ContractStatus St = ContractStatus;

            if (!(ContractStatus is ContractStatus_Contract))
                return 0;

            PaymentsPlanItem p = (ContractStatus as ContractStatus_Contract).PaymentsPlan.GetPrev(DateTime.Now);

            double planSumm = 0;
            double paymentSumm = 0;
            if (p != null)
                planSumm = (ContractStatus as ContractStatus_Contract).PaymentsPlan.SummaForDate(p.Date);

            if (St is ContractStatus_Contract)
                paymentSumm = (St as ContractStatus_Contract).Payments.SummaForDate(DateTime.Now);

            return planSumm - paymentSumm;
        }


        #endregion
    }



    
    

  


   



    
  

}
